﻿Public MustInherit Class StammdatenverwaltungAdapter(Of F As Form, L As StammdatenverwaltungListener(Of T), T As Base)
    Inherits KundeProjektTaskFormAdapter(Of F, L)

    Private Const SAVE_TEXT_NEW As String = "Speichern"
    Private Const SAVE_TEXT_EDIT As String = "Änderungen speichern"

    Private listView As ListView
    Private WithEvents btnDelete As Button
    Private WithEvents btnEdit As Button
    Private WithEvents btnSave As Button

    Private editEntity As T

    Private data As New List(Of T)

    Private columns As New List(Of String)

    Sub New(ByRef form As F)
        MyBase.New(form)
    End Sub

    Public Sub setListView(ByRef listView As ListView)
        Me.listView = listView
        Me.listView.View = View.Details
        Me.listView.FullRowSelect = True
    End Sub

    Public Sub setDeleteButton(ByRef btnDelete As Button)
        Me.btnDelete = btnDelete
    End Sub

    Public Sub setEditButton(ByRef btnEdit As Button)
        Me.btnEdit = btnEdit
    End Sub

    Public Sub setSaveButton(ByRef btnSave As Button)
        btnSave.Text = SAVE_TEXT_NEW
        Me.btnSave = btnSave
        checkFormEnable()
    End Sub

    Public Sub addColumn(ByVal displayName As String, ByVal realName As String, Optional ByVal width As Integer = 100)
        columns.Add(realName)
        Dim colHeader As New ColumnHeader()
        colHeader.Text = displayName
        colHeader.Width = width
        listView.Columns.Add(colHeader)
    End Sub

    Public Sub setData(ByVal data As List(Of T))
        Me.data = data
        listView.SuspendLayout()
        Dim selectedItems As List(Of T) = getSelectedLSVItems()
        listView.Items.Clear()
        For counter As Integer = 0 To data.Count - 1
            Dim lvi As ListViewItem = New ListViewItem(convertEntity(data(counter)))
            For Each selectedItem As T In selectedItems
                If data(counter).id = selectedItem.id Then
                    lvi.Selected = True
                    Exit For
                End If
            Next
            listView.Items.Add(lvi)
        Next
        listView.ResumeLayout()
    End Sub

    Private Function getSelectedLSVItems() As List(Of T)
        Dim result As New List(Of T)
        For Each index As Integer In Me.listView.SelectedIndices
            If hasEntity(index) Then
                result.Add(getEntity(index))
            End If
        Next
        Return result
    End Function

    Private Function convertEntity(ByVal entity As T) As String()
        Dim result As New List(Of String)
        For Each column As String In columns
            Dim field As System.Reflection.FieldInfo = entity.GetType.GetField(column)
            result.Add(field.GetValue(entity))
        Next
        Return result.ToArray()
    End Function

    Protected Function hasEntity(ByVal index As Integer) As Boolean
        If index < 0 Then
            Return False
        End If
        If index >= data.Count Then
            Return False
        End If
        Return True
    End Function

    Protected Overridable Function getEntity(ByVal index As Integer) As Base
        Return data(index)
    End Function

    Private Sub btnDelete_click() Handles btnDelete.Click
        Dim selectedValues As Integer = listView.SelectedIndices.Count
        If selectedValues = 0 Then
            showError("Bitte wählen sie einen Eintrag aus")
            Return
        End If

        Dim toDelete As New List(Of T)
        For Each index As Integer In listView.SelectedIndices
            toDelete.Add(getEntity(index))
        Next
        For Each entity As T In toDelete
            For Each listener As L In getObservable.getListeners
                listener.delete(entity)
            Next
        Next
    End Sub

    Private Sub btnEdit_click() Handles btnEdit.Click
        Dim selectedValues As Integer = listView.SelectedIndices.Count
        If selectedValues = 0 Then
            showError("Bitte wählen sie einen Eintrag aus")
            Return
        End If
        If selectedValues > 1 Then
            showError("Wählen Sie nur ein Eintrag aus")
            Return
        End If

        Me.btnSave.Text = SAVE_TEXT_EDIT
        Me.editEntity = getEntity(listView.SelectedIndices(0))

        setFormEntity(Me.editEntity)
    End Sub

    Protected MustOverride Sub setFormEntity(ByRef entity As T)

    Private Sub btnSave_click() Handles btnSave.Click
        Dim entity As T
        Try
            entity = getFormEntity(Me.editEntity)
            entity.validate()
        Catch exception As Exception
            showError(exception.Message)
            Exit Sub
        End Try
        For Each listener As L In getObservable().getListeners()
            listener.save(entity)
        Next
        clearForm()
        Me.editEntity = Nothing
        btnSave.Text = SAVE_TEXT_NEW
    End Sub

    Protected MustOverride Function getFormEntity(ByRef editEntity As T) As T

    Protected MustOverride Sub clearForm()

    Protected Overrides Sub onComboboxChange()
        checkFormEnable()
    End Sub

    Private Sub checkFormEnable()
        btnSave.Parent.Enabled = MyBase.areRequiredComboboxesFilled()
    End Sub

End Class
